﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;

using Sumen.Business.Data;
using Sumen.Business.Presenter.Inventory;
using Sumen.Library.Classes.Common;
using Sumen.Library.Enum;
using Sumen.Model.Model;

namespace Sumen.Business.Presenter.Sales
{
    public class OrdersPresenter
    {


        public int Update(List<orders_details> pOrdersDetailses, order pOrder)
        {
            using (sumenEntities objSumenEntities = new sumenEntities())
            {
                DbContextTransaction trans = objSumenEntities.Database.BeginTransaction();
                int result = 0;
                try
                {
                    //update orders
                    order oldOrder = objSumenEntities.orders.FirstOrDefault(p => p.Ord_ID == pOrder.Ord_ID);
                    oldOrder.Ord_Cash = pOrder.Ord_Cash;
                    oldOrder.Ord_Change = pOrder.Ord_Change;
                    oldOrder.Ord_Customer_Address = pOrder.Ord_Customer_Address;
                    oldOrder.Ord_Customer_Contact = pOrder.Ord_Customer_Contact;
                    oldOrder.Ord_Customer_ID = pOrder.Ord_Customer_ID;
                    oldOrder.Ord_Customer_Name = pOrder.Ord_Customer_Name;
                    oldOrder.Ord_DISTRICT_ID = pOrder.Ord_DISTRICT_ID;
                    oldOrder.Ord_Date_Orders = pOrder.Ord_Date_Orders;
                    oldOrder.Ord_Deposit = pOrder.Ord_Deposit;
                    oldOrder.Ord_Description = pOrder.Ord_Description;
                    oldOrder.Ord_Discount = pOrder.Ord_Discount;
                    oldOrder.Ord_DiscountRate = pOrder.Ord_DiscountRate;
                    oldOrder.Ord_IsOrder = pOrder.Ord_IsOrder;
                    oldOrder.Ord_Payment_Status = pOrder.Ord_Payment_Status;
                    oldOrder.Ord_Total_Amount = pOrder.Ord_Total_Amount;
                    oldOrder.Ord_VAT = pOrder.Ord_VAT;
                    objSumenEntities.SaveChanges();
                    //delete orders details
                    for (int i = 0; i < oldOrder.orders_details.Count; i++)
                    {
                        string osId = oldOrder.orders_details.ToList()[i].Ords_PRODUCT_DETAILS_ID;
                        orders_details ordersDetails = pOrdersDetailses.FirstOrDefault(p => p.Ords_ORDERS_ID == oldOrder.Ord_ID && p.Ords_PRODUCT_DETAILS_ID == osId);
                        if (ordersDetails == null)
                        {
                            orders_details deleteOrdersDetails =
                                objSumenEntities.orders_details.FirstOrDefault(
                                    p => p.Ords_ORDERS_ID == oldOrder.Ord_ID && p.Ords_PRODUCT_DETAILS_ID == osId);
                            objSumenEntities.orders_details.Remove(deleteOrdersDetails);
                            objSumenEntities.SaveChanges();
                        }
                    }
                    //update and add order details
                    for (int i = 0; i < pOrdersDetailses.Count; i++)
                    {
                        string osId = pOrdersDetailses[i].Ords_PRODUCT_DETAILS_ID;
                        orders_details oldOrderDetails = objSumenEntities.orders_details.FirstOrDefault(p => p.Ords_ORDERS_ID == oldOrder.Ord_ID && p.Ords_PRODUCT_DETAILS_ID == osId);
                        if (oldOrderDetails != null)
                        {
                            oldOrderDetails.Ords_Amount = pOrdersDetailses[i].Ords_Amount;
                            oldOrderDetails.Ords_CatId = pOrdersDetailses[i].Ords_CatId;
                            oldOrderDetails.Ords_Description = pOrdersDetailses[i].Ords_Description;
                            oldOrderDetails.Ords_Discount = pOrdersDetailses[i].Ords_Discount;
                            oldOrderDetails.Ords_DiscountRate = pOrdersDetailses[i].Ords_DiscountRate;
                            oldOrderDetails.Ords_IsOrders = pOrdersDetailses[i].Ords_IsOrders;
                            oldOrderDetails.Ords_IsOrders_Image = pOrdersDetailses[i].Ords_IsOrders_Image;
                            oldOrderDetails.Ords_IsReturned = pOrdersDetailses[i].Ords_IsReturned;
                            oldOrderDetails.Ords_PRODUCT_DETAILS_ID = pOrdersDetailses[i].Ords_PRODUCT_DETAILS_ID;
                            oldOrderDetails.Ords_Product_Name = pOrdersDetailses[i].Ords_Product_Name;
                            oldOrderDetails.Ords_Quantity = pOrdersDetailses[i].Ords_Quantity;
                            oldOrderDetails.Ords_Surcharge = pOrdersDetailses[i].Ords_Surcharge;
                            oldOrderDetails.Ords_UnitPrice = pOrdersDetailses[i].Ords_UnitPrice;
                            objSumenEntities.SaveChanges();
                        }
                        else
                        {
                            orders_details newOrdersDetails = new orders_details();
                            newOrdersDetails.Ords_Amount = pOrdersDetailses[i].Ords_Amount;
                            newOrdersDetails.Ords_CatId = pOrdersDetailses[i].Ords_CatId;
                            newOrdersDetails.Ords_Description = pOrdersDetailses[i].Ords_Description;
                            newOrdersDetails.Ords_Discount = pOrdersDetailses[i].Ords_Discount;
                            newOrdersDetails.Ords_DiscountRate = pOrdersDetailses[i].Ords_DiscountRate;
                            newOrdersDetails.Ords_IsOrders = pOrdersDetailses[i].Ords_IsOrders;
                            newOrdersDetails.Ords_IsOrders_Image = pOrdersDetailses[i].Ords_IsOrders_Image;
                            newOrdersDetails.Ords_IsReturned = pOrdersDetailses[i].Ords_IsReturned;
                            newOrdersDetails.Ords_ORDERS_ID = pOrder.Ord_ID;
                            newOrdersDetails.Ords_PRODUCT_DETAILS_ID = pOrdersDetailses[i].Ords_PRODUCT_DETAILS_ID;
                            newOrdersDetails.Ords_Product_Name = pOrdersDetailses[i].Ords_Product_Name;
                            newOrdersDetails.Ords_Quantity = pOrdersDetailses[i].Ords_Quantity;
                            newOrdersDetails.Ords_Surcharge = pOrdersDetailses[i].Ords_Surcharge;
                            newOrdersDetails.Ords_UnitPrice = pOrdersDetailses[i].Ords_UnitPrice;
                            objSumenEntities.orders_details.Add(newOrdersDetails);
                            objSumenEntities.SaveChanges();
                        }
                    }

                    result = 1;
                    if (pOrder.Ord_Payment_Status == (int)EnumOrdersStatus.Paid)
                    {
                        //add outward details
                        List<inventory_details> listInventoryDetailses = new List<inventory_details>();
                        for (int i = 0; i < pOrdersDetailses.Count; i++)
                        {
                            inventory_details inventoryDetails = new inventory_details();
                            inventoryDetails.Invd_PRODUCT_DETAILS_ID = pOrdersDetailses[i].Ords_PRODUCT_DETAILS_ID;
                            inventoryDetails.Invd_Product_Name = pOrdersDetailses[i].Ords_Product_Name;
                            inventoryDetails.Invd_Quantity = pOrdersDetailses[i].Ords_Quantity;
                            inventoryDetails.Invd_Amount = pOrdersDetailses[i].Ords_Amount;
                            inventoryDetails.Invd_Price = pOrdersDetailses[i].Ords_UnitPrice;
                            //cho nay không ổn, cần xác định vị trí kho để lấy sản phẩm chính xác
                            inventory invent = (from p in objSumenEntities.inventories select p).FirstOrDefault(p => p.Inv_Quantity > 0 && p.Inv_PRODUCT_DETAILS_ID == inventoryDetails.Invd_PRODUCT_DETAILS_ID);
                            inventoryDetails.Invd_Stock_ID = invent.Inv_Stock_ID;
                            inventoryDetails.Invd_INENTORY_ID = invent.Inv_ID;
                            listInventoryDetailses.Add(inventoryDetails);
                        }
                        //add outward
                        stock_outward stockOutward = new stock_outward();
                        stockOutward.Outw_ID = pOrder.Ord_Code;
                        stockOutward.Outw_Customer_ID = pOrder.Ord_Customer_ID;
                        stockOutward.Outw_Customer_Name = pOrder.Ord_Customer_Name;
                        stockOutward.Outw_Customer_Address = pOrder.Ord_Customer_Address;
                        stockOutward.Outw_Customer_Contact = pOrder.Ord_Customer_Contact;
                        stockOutward.Outw_RefDate = pOrder.Ord_Date_Orders;
                        stockOutward.Outw_Description = pOrder.Ord_Description;
                        stockOutward.Outw_RefType = (int)EnumRefType.Sales;
                        // stockOutward.Outw_Stock_id =  string.Empty;stockOutward.Outw_Amount = pOrder.Ord_Total_Amount;
                        stockOutward.Outw_Payment = 1;
                        stockOutward.Outw_Actived = 1;
                        stockOutward.Outw_DiscountRate = pOrder.Ord_DiscountRate;
                        stockOutward.Outw_Discount = pOrder.Ord_Discount;
                        stockOutward.Outw_Amount = pOrdersDetailses.Sum(p => p.Ords_Amount);
                        stockOutward.Outw_User_ID = ClsPublic.User.User_Username;
                        OutwardPresenter outwardPresenter = new OutwardPresenter();
                        result = outwardPresenter.Add(listInventoryDetailses, stockOutward);
                    }
                    if (result > 0)
                    {
                        trans.Commit();
                        return 1;
                    }
                    else
                    {
                        trans.Rollback();
                        return 0;
                    }

                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    ClsMsgBox.LoiChung(ex, false);
                    return 0;
                }

            }
        }




        //public int Add(order pOrder)
        //{
        //    trans = objSumenEntities.Database.BeginTransaction();
        //    int result = 0;
        //    try
        //    {
        //        //add orders
        //        objSumenEntities.orders.Add(pOrder);
        //        result = objSumenEntities.SaveChanges();
        //        // trans.Commit();
        //        //add order details

        //        //for (int i = 0; i < pOrdersDetailses.Count; i++)
        //        //{
        //        //    pOrdersDetailses[i].Ords_ORDERS_ID = pOrder.Ord_ID;
        //        //    pOrdersDetailses[i].Ords_Surcharge = pOrdersDetailses[i].Ords_Surcharge ?? (pOrdersDetailses[i].Ords_Surcharge = 0);
        //        //    objSumenEntities.orders_details.Add(pOrdersDetailses[i]);
        //        //    result = objSumenEntities.SaveChanges();
        //        //    trans.Commit();
        //        //}

        //        if (pOrder.Ord_Payment_Status == (int)EnumOrdersStatus.Paid)
        //        {
        //            //add outward details
        //            List<inventory_details> listInventoryDetailses = new List<inventory_details>();
        //            for (int i = 0; i < pOrder.orders_details.Count; i++)
        //            {
        //                //order details-->sua description=""

        //                inventory_details inventoryDetails = new inventory_details();
        //                inventoryDetails.Invd_PRODUCT_DETAILS_ID = pOrder.orders_details.ToList()[i].Ords_PRODUCT_DETAILS_ID;
        //                inventoryDetails.Invd_Product_Name = pOrder.orders_details.ToList()[i].Ords_Product_Name;
        //                inventoryDetails.Invd_Quantity = pOrder.orders_details.ToList()[i].Ords_Quantity;
        //                inventoryDetails.Invd_Amount = pOrder.orders_details.ToList()[i].Ords_Amount;
        //                inventoryDetails.Invd_Price = pOrder.orders_details.ToList()[i].Ords_UnitPrice;
        //                //cho nay không ổn, cần xác định vị trí kho để lấy sản phẩm chính xác
        //                inventory invent = (from p in objSumenEntities.inventories select p).FirstOrDefault(p => p.Inv_Quantity > 0 && p.Inv_PRODUCT_DETAILS_ID == inventoryDetails.Invd_PRODUCT_DETAILS_ID);
        //                inventoryDetails.Invd_Stock_ID = invent.Inv_Stock_ID;
        //                inventoryDetails.Invd_INENTORY_ID = invent.Inv_ID;
        //                listInventoryDetailses.Add(inventoryDetails);
        //            }
        //            //add outward
        //            stock_outward stockOutward = new stock_outward();
        //            stockOutward.Outw_ID = pOrder.Ord_Code;
        //            stockOutward.Outw_Customer_ID = pOrder.Ord_Customer_ID;
        //            stockOutward.Outw_Customer_Name = pOrder.Ord_Customer_Name;
        //            stockOutward.Outw_Customer_Address = pOrder.Ord_Customer_Address;
        //            stockOutward.Outw_Customer_Contact = pOrder.Ord_Customer_Contact;
        //            stockOutward.Outw_RefDate = pOrder.Ord_Date_Orders;
        //            stockOutward.Outw_Description = pOrder.Ord_Description;
        //            stockOutward.Outw_RefType = (int)EnumRefType.Sales;
        //            // stockOutward.Outw_Stock_id =  string.Empty;stockOutward.Outw_Amount = pOrder.Ord_Total_Amount;
        //            stockOutward.Outw_Payment = 1;
        //            stockOutward.Outw_Actived = 1;
        //            stockOutward.Outw_DiscountRate = pOrder.Ord_DiscountRate;
        //            stockOutward.Outw_Discount = pOrder.Ord_Discount;
        //            stockOutward.Outw_Amount = pOrder.orders_details.Sum(p => p.Ords_Amount);
        //            stockOutward.Outw_User_ID = ClsPublic.User.User_Username;
        //            OutwardPresenter outwardPresenter = new OutwardPresenter();
        //            result = outwardPresenter.Add(listInventoryDetailses, stockOutward);

        //        }
        //        if (result > 0)
        //        {

        //            trans.Commit();

        //            return 1;
        //        }
        //        else
        //        {
        //            trans.Rollback();
        //            return 0;
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        trans.Rollback();
        //        ClsMsgBox.LoiChung(ex, false);
        //        return 0;
        //    }

        //    // }
        //}


        public int Add(order pOrder)
        {
            Dao dao = new Dao(true, true);
            //using ()
            //{
            // trans = objSumenEntities.Database.BeginTransaction();
            int result = 0;
            //try
            //{
            //add orders
            //objSumenEntities.orders.Add(pOrder);
            //result = objSumenEntities.SaveChanges();
            result = dao.Add(pOrder);
            // trans.Commit();
            //add order details

            //for (int i = 0; i < pOrdersDetailses.Count; i++)
            //{
            //    pOrdersDetailses[i].Ords_ORDERS_ID = pOrder.Ord_ID;
            //    pOrdersDetailses[i].Ords_Surcharge = pOrdersDetailses[i].Ords_Surcharge ?? (pOrdersDetailses[i].Ords_Surcharge = 0);
            //    objSumenEntities.orders_details.Add(pOrdersDetailses[i]);
            //    result = objSumenEntities.SaveChanges();
            //    trans.Commit();
            //}

            if (pOrder.Ord_Payment_Status == (int)EnumOrdersStatus.Paid)
            {
                //add outward details
                List<inventory_details> listInventoryDetailses = new List<inventory_details>();
                for (int i = 0; i < pOrder.orders_details.Count; i++)
                {
                    //order details-->sua description=""

                    inventory_details inventoryDetails = new inventory_details();
                    inventoryDetails.Invd_PRODUCT_DETAILS_ID = pOrder.orders_details.ToList()[i].Ords_PRODUCT_DETAILS_ID;
                    inventoryDetails.Invd_Product_Name = pOrder.orders_details.ToList()[i].Ords_Product_Name;
                    inventoryDetails.Invd_Quantity = pOrder.orders_details.ToList()[i].Ords_Quantity;
                    inventoryDetails.Invd_Amount = pOrder.orders_details.ToList()[i].Ords_Amount;
                    inventoryDetails.Invd_Price = pOrder.orders_details.ToList()[i].Ords_UnitPrice;
                    //cho nay không ổn, cần xác định vị trí kho để lấy sản phẩm chính xác
                    inventory invent =
                        dao.GetContext<inventory>().Set<inventory>().FirstOrDefault(p =>
                                    p.Inv_Quantity > 0 &&
                                    p.Inv_PRODUCT_DETAILS_ID == inventoryDetails.Invd_PRODUCT_DETAILS_ID);
                    //(from p in objSumenEntities.inventories select p).
                    //FirstOrDefault(p => p.Inv_Quantity > 0 && p.Inv_PRODUCT_DETAILS_ID == inventoryDetails.Invd_PRODUCT_DETAILS_ID);
                    inventoryDetails.Invd_Stock_ID = invent.Inv_Stock_ID;
                    inventoryDetails.Invd_INENTORY_ID = invent.Inv_ID;
                    listInventoryDetailses.Add(inventoryDetails);
                }
                //add outward
                stock_outward stockOutward = new stock_outward();
                stockOutward.Outw_ID = pOrder.Ord_Code;
                stockOutward.Outw_Customer_ID = pOrder.Ord_Customer_ID;
                stockOutward.Outw_Customer_Name = pOrder.Ord_Customer_Name;
                stockOutward.Outw_Customer_Address = pOrder.Ord_Customer_Address;
                stockOutward.Outw_Customer_Contact = pOrder.Ord_Customer_Contact;
                stockOutward.Outw_RefDate = pOrder.Ord_Date_Orders;
                stockOutward.Outw_Description = pOrder.Ord_Description;
                stockOutward.Outw_RefType = (int)EnumRefType.Sales;
                // stockOutward.Outw_Stock_id =  string.Empty;stockOutward.Outw_Amount = pOrder.Ord_Total_Amount;
                stockOutward.Outw_Payment = 1;
                stockOutward.Outw_Actived = 1;
                stockOutward.Outw_DiscountRate = pOrder.Ord_DiscountRate;
                stockOutward.Outw_Discount = pOrder.Ord_Discount;
                stockOutward.Outw_Amount = pOrder.orders_details.Sum(p => p.Ords_Amount);
                stockOutward.Outw_User_ID = ClsPublic.User.User_Username;
                OutwardPresenter outwardPresenter = new OutwardPresenter();
                result = outwardPresenter.Add(listInventoryDetailses, stockOutward);
            }
            if (result > 0)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }

        public int Delete(List<orders_details> pOrdersDetailses, order pOrder)
        {
            using (sumenEntities objSumenEntities = new sumenEntities())
            {
                DbContextTransaction trans = objSumenEntities.Database.BeginTransaction();
                try
                {
                    for (int i = 0; i < pOrdersDetailses.Count; i++)
                    {
                        long osId = pOrdersDetailses[i].Ords_ID;
                        //orders_details ordersDetails = pOrdersDetailses.FirstOrDefault(p => p.Ords_ID == osId);
                        //if (ordersDetails == null)
                        //{
                        objSumenEntities.orders_details.Remove(objSumenEntities.orders_details.FirstOrDefault(p => p.Ords_ID == osId));
                        objSumenEntities.SaveChanges();
                        //}
                    }
                    objSumenEntities.orders.Remove(objSumenEntities.orders.FirstOrDefault(p => p.Ord_ID == pOrder.Ord_ID));
                    objSumenEntities.SaveChanges();
                    trans.Commit();
                    return 1;
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    ClsMsgBox.LoiChung(ex, false);
                    return 0;
                }
            }

        }


        public string GetNewCodeOrders(object pDate)
        {
            using (sumenEntities obj = new sumenEntities())
            {
                DateTime pDateTime = (DateTime)pDate;
                string prefix = ClsPublic.ORDERS_PREFIX_CODE;
                prefix = prefix + "-" + pDateTime.ToString("ddMMyy") + "-";
                DateTime dateNowStart = new DateTime(pDateTime.Year, pDateTime.Month, pDateTime.Day);
                DateTime dateNowEnd = new DateTime(pDateTime.Year, pDateTime.Month, pDateTime.Day).AddDays(1).AddMinutes(-1);
                long countMax = (from p in obj.orders where p.Ord_Date_Orders >= dateNowStart && p.Ord_Date_Orders <= dateNowEnd select p).Max(m => m.Ord_Sorted) ?? 0;
                var query = countMax + 1;
                string count = query.ToString().PadLeft(4, '0');
                return prefix + count;
            }
        }


        public order GetById(object pId)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                objEntities.Configuration.LazyLoadingEnabled = false;
                objEntities.Configuration.ProxyCreationEnabled = false;
                long id = Convert.ToInt64(pId);
                order orders = objEntities.orders.FirstOrDefault(p => p.Ord_ID == id);
                objEntities.Entry(orders).Collection(p => p.orders_details).Load();
                return orders;
            }
        }


        /// <summary>
        /// Search orders from date
        /// </summary>
        /// <param name="pValue">Date</param>
        /// <returns>List orders</returns>
        public ICollection<order> GetByKey(object pValue)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                DateTime date = pValue is DateTime ? (DateTime)pValue : DateTime.Today;
                var query = objEntities.orders.Where(p => p.Ord_Date_Orders >= date);
                return query.ToList();
            }
        }

        /// <summary>
        /// Search orders from date and customer
        /// </summary>
        /// <param name="pValue">Date</param>
        /// <param name="pCustomerId">Customer id</param>
        /// <returns>List orders</returns>
        public ICollection<order> GetByKey(object pValue, string pCustomerId)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                objEntities.Configuration.LazyLoadingEnabled = false;
                objEntities.Configuration.ProxyCreationEnabled = false;
                DateTime date = pValue is DateTime ? (DateTime)pValue : DateTime.Today;
                var query = objEntities.orders.Where(p => p.Ord_Date_Orders >= date && (string.IsNullOrEmpty(pCustomerId) ? p.Ord_Customer_ID != null : p.Ord_Customer_ID == pCustomerId)).ToList();
                return query;
            }
        }

    }
}
